package com.robot.member.controller;

import com.robot.member.client.SmsClient;
import com.robot.member.pojo.Member;
import com.robot.member.pojo.vo.Authorization;
import com.robot.member.pojo.vo.AuthorizationAccessToken;
import com.robot.member.pojo.vo.WeChatInfo;
import com.robot.member.service.MemberService;
import com.robot.member.service.WeChatService;
import entity.Result;
import entity.Sms;
import entity.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import util.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author wuyunbin
 */
@RestController
@CrossOrigin
@RequestMapping("/member")
public class LoginController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MemberService memberService;

    @Autowired
    private WeChatService weChatService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private BCryptPasswordEncoder encoder;
    @Autowired
    private IdWorker idWorker;

    @Autowired
    private CheckUtil checkUtil;
    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private SmsClient smsClient;

    @Value("${sys.member.avatar}")
    private String avatar;

    /**
     * 分享送码豆数量
     */
    @Value("${sys.member.afterShareSendBeans}")
    private int afterShareSendBeans;

    /**
     * 手机验证码登录 没有注册时自动注册
     *
     * @param checkCode
     * @param member
     * @return
     */
    @RequestMapping(value = "/login/phone/{checkCode}", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public Result registerPhone(@PathVariable String checkCode, @RequestBody Member member) {
        //判断手机号是否合法
        String phone = member.getPhone();
        if (!checkUtil.checkPhone(phone)) {
            return new Result(StatusCode.ERROR_INVALID_PHONE);
        }
        //判断验证码
        checkCode = checkCode.trim();
        if ("".equals(checkCode)) {
            return new Result(StatusCode.ERROR_VERIFICATION_CODE);
        }
        Sms sms = new Sms("member", phone, "login");

        if (!smsClient.isCheckCodeExpire(sms)) {
            return new Result(StatusCode.ERROR_VERIFICATION_CODE_EXPIRED);
        }
        if (!smsClient.isCorrectCheckCode(sms, checkCode)) {
            return new Result(StatusCode.ERROR_VERIFICATION_CODE);
        }
        //判断手机号是否存在，不存在则自动注册
        Member memberInDb = memberService.findByPhone(phone);

        if (memberInDb == null) {
            memberInDb = new Member();
            //雪花分布式ID生成器
            memberInDb.setId(BinaryUtil.decimal2Base62(idWorker.nextId()));
            memberInDb.setPhone(phone);
            memberInDb.setNickname(phone);
            memberInDb.setAvatar(avatar);
            memberInDb.setLastLoginIp(IpUtil.getIpAddr(request));
            memberInDb.setBeans(0);
            memberInDb.setGoldenBeans(0);
            memberInDb.setIsPlus("0");
            if (member.getRecommendId() != null && !"".equals(member.getRecommendId())) {
                if (memberService.findById(member.getRecommendId()) == null) {
                    return new Result(StatusCode.ERROR_RECOMMEND_ID_INVALID);
                } else {
                    memberInDb.setRecommendId(member.getRecommendId());
                }
            }
            memberService.add(memberInDb);
        } else {
            logger.info(memberInDb.toString());
            memberInDb.setLastLoginIp(IpUtil.getIpAddr(request));
            memberInDb.setLastLoginTime(LocalDateTime.now());
            memberService.update(memberInDb);
        }

        String memberId = memberInDb.getId();
        String role = "member";
        String token = jwtUtil.createJwt(memberId, memberInDb.getPhone(), role);
        String openId = memberInDb.getOpenId();
        Authorization authorization = new Authorization(memberId, openId, memberInDb.getNickname(), role, token);
        if (openId != null) {
            authorization.setOpenId(openId);
        }

        //删除redis里面的验证码
        smsClient.deleteCheckCode(sms);
        return new Result(StatusCode.SUCCESS_LOGIN, authorization);
    }


    /**
     * 手机号密码登录
     *
     * @param member
     * @return
     */
    @PostMapping("/login")
    @Transactional(rollbackFor = Exception.class)
    public Result loginByPhoneAndPassword(@RequestBody Member member) {
        //判断手机号是否合法
        if (!checkUtil.checkPhone(member.getPhone())) {
            return new Result(StatusCode.ERROR_INVALID_PHONE);
        }
        if (member.getPassword() == null || "".equals(member.getPassword())) {
            return new Result(StatusCode.ERROR_PASSWORD_REQUIRED);
        }
        Member memberInDb = memberService.findByPhone(member.getPhone());
        logger.info("memberInDb=" + memberInDb);
        if (memberInDb == null) {
            return new Result(StatusCode.ERROR_USER_DOES_NOTE_EXIST);
        }
        String enable = "1";
        if (!enable.equals(memberInDb.getStatus())) {
            return new Result(StatusCode.ERROR_USER_INVALID);
        }
        if (!encoder.matches(member.getPassword(), memberInDb.getPassword())) {
            return new Result(StatusCode.ERROR_PASSWORD_WRONG);
        }

        String role = "member";
        String memberId = memberInDb.getId();
        String token = jwtUtil.createJwt(memberInDb.getId(), member.getPhone(), role);


        Authorization authorization = new Authorization(memberId, memberInDb.getOpenId(), memberInDb.getNickname(), role, token);
        logger.info(authorization.toString());

        memberInDb.setLastLoginTime(LocalDateTime.now());
        memberInDb.setLastLoginIp(IpUtil.getIpAddr(request));

        logger.info(memberInDb.toString());
        memberService.update(memberInDb);
        return new Result(StatusCode.SUCCESS_LOGIN, authorization);
    }


    /**
     * 微信登录
     * 通过微信授权返回的code来获取授权access_token和open_id，从而实现登录
     *
     * @param code 微信返回的code
     * @return result 里面包含了一个 Authorization
     */
    @RequestMapping(value = "/loginByWeChat/{code}", method = RequestMethod.GET)
    public Result loginByWeChat(@PathVariable String code) {
        logger.info("code=" + code);
        //通过code获取授权accessToken和openId
        AuthorizationAccessToken accessToken = weChatService.getAuthorizationAccessToken(code);
        logger.info("accessToken=" + accessToken.toString());
        //通过accessToken和openId 获取微信用户信息
        WeChatInfo weChatInfo = weChatService.getUserInfoByAuthorizationAccessTokenAndOpenId(accessToken.getAccessToken(), accessToken.getOpenId());
        //检查这个微信号是否已经是会员，如果是直接登录，如果不是则注册之后再登录
        Member member = memberService.findByOpenId(weChatInfo.getOpenId());
        if (member == null) {
            //注册
            member = memberService.addByWeChat(weChatInfo);
        }
        logger.info("开始组装返回信息");
        //登录
        String role = "member";
        String memberId = member.getId();
        String token = jwtUtil.createJwt(memberId, member.getOpenId(), role);
        Authorization authorization = new Authorization(memberId, weChatInfo.getOpenId(), member.getNickname(), role, token);
        logger.info(authorization.toString());
        return new Result(StatusCode.SUCCESS, authorization);
    }


}
